#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;

double beta = 2;
int p = 3;
int L = -1;
int U = 1;

inline double pow(double x,int p){
	double ans = 1;
        if(p>0){
            for(int i=0;i<p;i++) ans*=x;
	        return ans;	
        }
        else if(p<0){
            for(int i=0;i<-p;i++) ans/=x;
	        return ans;
        }
        return 1;
}

void OU(){
    cout << "The UFL is " << pow(beta,L) << endl;
    cout << "The OFL is " << pow(beta,U)*(beta-pow(beta,1-p)) << endl;
}

vector<double> normal;
double ans;

void perm(int p,int end,int times){
    if(p>=end){
        if(ans >=1){
            normal.push_back(ans*pow(beta,times));
            normal.push_back(-ans*pow(beta,times));
        }
        return;
    }
    for(int j=0;j<beta;j++){
        ans/=beta;
        ans+=j;
        perm(p+1,end,times);
        ans-=j;
        ans*=beta;
    }
}
void all_normal(){
    for(int ind=L;ind<=U;ind++){
        perm(0,p,ind);
    }
}
void print_normal(){
    //normal.push_back(0);
    sort(normal.begin(),normal.end());
    cout << "The size of FPN is " << normal.size() << endl;
    for(int i=0;i<normal.size();i++) cout << normal[i] << " ";
    cout <<endl;
}
void plot_normal(){
    ofstream outfile;
    outfile.open("1D.dat");
    outfile << "[";
    for(int i=0;i<normal.size();i++){
    outfile << normal[i];
    if(i<normal.size()-1) outfile << ",";
    }
    outfile << "]" <<endl;
    outfile << "[";
    for(int i=0;i<normal.size();i++){
    outfile << 0;
    if(i<normal.size()-1) outfile << ",";
    }
    outfile << "]" <<endl;
}
void plot_subnormal(){
    ofstream outfile;
    outfile.open("2D.dat");
    outfile << "[";
    for(int i=0;i<normal.size();i++){
    outfile << normal[i];
    if(i<normal.size()-1) outfile << ",";
    }
    outfile << "]" <<endl;
    outfile << "[";
    for(int i=0;i<normal.size();i++){
    outfile << 0;
    if(i<normal.size()-1) outfile << ",";
    }
    outfile << "]" <<endl;
}
void byperm(int p,int end,int times){
    if(p>=end){
        if(ans <1 && ans>0){
            normal.push_back(ans*pow(beta,times));
            normal.push_back(-ans*pow(beta,times));
        }
        return;
    }
    for(int j=0;j<beta;j++){
        ans/=beta;
        ans+=j;
        byperm(p+1,end,times);
        ans-=j;
        ans*=beta;
    }
}
void subnormal(){
    byperm(0,p,L);
}
int main(){
    normal.push_back(0);
    OU();
    all_normal();
    print_normal();
    plot_normal();
    subnormal();
    print_normal();
    plot_subnormal();
}